package businesslogic.chooseCourseBl;

import java.rmi.Naming;
import java.util.ArrayList;

import po.chooseCoursePO.ChooseCoursePO;
import po.userPO.StudentPO;
import po.userPO.UserPO;
import dataservice.ResultMessage;
import dataservice.chooseCourseDataService.ChooseCourseDatabaseService;
import dataservice.userDataService.UserDatabaseService;
import vo.chooseCourseVO.ChooseCourseVO;
import vo.courseVO.CourseVO;
import vo.userVO.StudentVO;
import businesslogic.courseBl.CourseController;
import businesslogicservice.chooseCourseblservice.*;

public class ChooseCourse implements ChooseCourseBLService{
	
	private String userId;
	public static final int NOW_TERM=3;
	private static final String ADDRESS_STRING="localhost";
	
	public ChooseCourse(String userId) {
		this.userId = userId;
	}

	@Override
	public ArrayList<ChooseCourseVO> getAllChooseCourseRecord() throws Exception{
		ArrayList<ChooseCourseVO> chooseCourseVOlist=new ArrayList<ChooseCourseVO>();
		try {
			ChooseCourseDatabaseService chooseCourseDatabaseService
			  =(ChooseCourseDatabaseService)Naming.lookup("rmi://"+ADDRESS_STRING+":8888/chooseCourseData");
			
			ArrayList<ChooseCoursePO> chooseCoursePOs
			        =chooseCourseDatabaseService.findChooseCourseByIDAndTerm(userId, NOW_TERM);
			for(ChooseCoursePO choose:chooseCoursePOs){
				ChooseCourseVO chooseCourseVO=new ChooseCourseVO(choose.getStudentId(),
			   choose.getStudentName(),choose.getCourseId(),choose.getCourseName(),choose.getScore(),choose.getCredit(),choose.getTerm(),choose.getAttribute());
				chooseCourseVOlist.add(chooseCourseVO);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
		return chooseCourseVOlist;	
	}

	@Override
	public ArrayList<StudentVO> getStuList(String courseId) throws Exception {
		ArrayList<StudentVO> studentVOs=new ArrayList<>();
		try {
			ChooseCourseDatabaseService chooseCourseDatabaseService
			  =(ChooseCourseDatabaseService)Naming.lookup("rmi://"+ADDRESS_STRING+":8888/chooseCourseData");
			
			UserDatabaseService userDatabaseService=
					(UserDatabaseService)Naming.lookup("rmi://"+ADDRESS_STRING+":8888/userData");
			ArrayList<ChooseCoursePO> chooseCoursePOs
	        =chooseCourseDatabaseService.findTeaCourse(courseId);
			ArrayList<StudentPO> studentPOs=new ArrayList<>();
			for(ChooseCoursePO chooseCoursePO:chooseCoursePOs){
				StudentPO studentPO=(StudentPO) userDatabaseService.find(chooseCoursePO.getStudentId());
				studentPOs.add(studentPO);
			}
			for(StudentPO studentPO:studentPOs){
				StudentVO studentVO=new StudentVO(studentPO.getId(),studentPO.getName()
						     ,studentPO.getDepartmentId(),studentPO.getGrade());
				studentVOs.add(studentVO);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
		return studentVOs;
	}


	@Override
	public ResultMessage chooseCourse(ArrayList<CourseVO> courseVOs, StudentVO studentVO) throws Exception {
		ResultMessage resultMessage=null;
		ChooseCourseDatabaseService chooseCourseDatabaseService;
		
		try {
			 chooseCourseDatabaseService=(ChooseCourseDatabaseService)Naming.lookup("rmi://"+ADDRESS_STRING+":8888/chooseCourseData");
			 
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
		
		int afterNum=courseVOs.size();
		if (afterNum>4) {
			return ResultMessage.MAX_NUM;
		}
		
		for(CourseVO courseVO:courseVOs){
			ChooseCoursePO chooseCoursePO=new ChooseCoursePO(studentVO.getId(),studentVO.getName()
				     ,courseVO.getCourseId(),courseVO.getCourseName(),0,courseVO.getCredit(),NOW_TERM,courseVO.getAttribute());
			 resultMessage= chooseCourseDatabaseService.insertTemp(chooseCoursePO);
		}
	
		return resultMessage;
	}

	@Override
	public ResultMessage deleteAChooseCourse(ChooseCourseVO vo) throws Exception {
		ResultMessage resultMessage=null;
		ChooseCoursePO chooseCoursePO=new ChooseCoursePO(vo.getStudentId(),vo.getStudentName(),
				                          vo.getCourseId(),vo.getCourseName(),vo.getScore(),vo.getCreidt(),NOW_TERM,vo.getAttribute());
		try {
			ChooseCourseDatabaseService chooseCourseDatabaseService
			  =(ChooseCourseDatabaseService)Naming.lookup("rmi://"+ADDRESS_STRING+":8888/chooseCourseData");
			resultMessage=chooseCourseDatabaseService.delete(chooseCoursePO);
			
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
		return resultMessage;
	}

	@Override
	public ResultMessage setScore(ChooseCourseVO vo,double score) throws Exception {
		ResultMessage resultMessage=null;
		ChooseCoursePO chooseCoursePO=new ChooseCoursePO(vo.getStudentId(),vo.getStudentName(),vo.getCourseId(),vo.getCourseName(),
				                   score,vo.getCreidt(),NOW_TERM,vo.getAttribute());
		try {
			ChooseCourseDatabaseService chooseCourseDatabaseService
			  =(ChooseCourseDatabaseService)Naming.lookup("rmi://"+ADDRESS_STRING+":8888/chooseCourseData");
			resultMessage=chooseCourseDatabaseService.update(chooseCoursePO);
			
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
		return resultMessage;
	}

	
	@Override
	public double getScore(ChooseCourseVO vo) throws Exception {
		double score=0;
		ChooseCoursePO chooseCoursePO=new ChooseCoursePO(vo.getStudentId(),vo.getStudentName(),
				                       vo.getCourseId(),vo.getCourseName(),vo.getScore(),vo.getCreidt(),NOW_TERM,vo.getAttribute());
		try {
			ChooseCourseDatabaseService chooseCourseDatabaseService
			  =(ChooseCourseDatabaseService)Naming.lookup("rmi://"+ADDRESS_STRING+":8888/chooseCourseData");
			score=chooseCourseDatabaseService.getScore(chooseCoursePO);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
		return score;
	}


	@Override
	public ArrayList<CourseVO> getMyCourse() throws Exception {
		ArrayList<ChooseCourseVO> chooseCourseVOs=getChooseCourseByTerm(NOW_TERM);
		ArrayList<CourseVO> courseVOs=new ArrayList<>();
		CourseController courseController=new CourseController(userId);
		for(ChooseCourseVO chooseCourseVO:chooseCourseVOs){
			courseVOs.add(courseController.getCourse(chooseCourseVO.getCourseId()));
		}
		return courseVOs;
	}
	
	
	@Override
	public ArrayList<ChooseCourseVO> getChooseCourseByTerm(int term) throws Exception {
		ArrayList<ChooseCourseVO> chooseCourseVOlist=new ArrayList<ChooseCourseVO>();
		try {
	
			ChooseCourseDatabaseService chooseCourseDatabaseService
			  =(ChooseCourseDatabaseService)Naming.lookup("rmi://"+ADDRESS_STRING+":8888/chooseCourseData");
			
			ArrayList<ChooseCoursePO> chooseCoursePOs
			        =chooseCourseDatabaseService.findChooseCourseByIDAndTerm(userId, term);
			
			for(ChooseCoursePO choose:chooseCoursePOs){
				ChooseCourseVO chooseCourseVO=new ChooseCourseVO(choose.getStudentId(),
			   choose.getStudentName(),choose.getCourseId(),choose.getCourseName(),choose.getScore(),choose.getCredit(),choose.getTerm(),choose.getAttribute());
				chooseCourseVOlist.add(chooseCourseVO);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
		return chooseCourseVOlist;
	}
	
	public void CalculateGPA(String department) throws Exception{
		          
		try {
			UserDatabaseService userDatabaseService=
					           (UserDatabaseService)Naming.lookup("rmi://"+ADDRESS_STRING+":8888/userData");
			ChooseCourseDatabaseService chooseCourseDatabaseService=
					        (ChooseCourseDatabaseService)Naming.lookup("rmi://"+ADDRESS_STRING+":8888/chooseCourseData");
			ArrayList<UserPO> student=userDatabaseService.findAllByDepartment(UserPO.STUDENT,department);
			for(UserPO userPO:student){
				ArrayList<ChooseCoursePO> chooseCoursePOs=chooseCourseDatabaseService.findChooseCourseByIDAndTerm(userPO.getId(), NOW_TERM);
				ArrayList<ChooseCoursePO> chooseCoursePOs2=chooseCourseDatabaseService.findStuCourse(userPO.getId());
				int totalCreditgpa=0;
				double creditMulScore=0;
				int totalChooseCredit=0;
				int totalCredit=0;
				for(ChooseCoursePO chooseCoursePO:chooseCoursePOs){
					if (chooseCoursePO.getScore()==0) {
						continue;
					}
					creditMulScore+=chooseCoursePO.getCredit()*chooseCoursePO.getScore();
					totalCreditgpa+=chooseCoursePO.getCredit();
					if (chooseCoursePO.getAttribute().equals("开放选修")){
						totalChooseCredit+=chooseCoursePO.getCredit();
					}
				}
				for (ChooseCoursePO chooseCoursePO:chooseCoursePOs2){
					totalCredit+=chooseCoursePO.getCredit();
					if (chooseCoursePO.getAttribute().equals("开放选修")){
						totalChooseCredit+=chooseCoursePO.getCredit();
					}
				}
				double resultGPA=0;
				if (totalCreditgpa==0){
					continue;
				} else {
					resultGPA=creditMulScore/(totalCreditgpa*20);
					resultGPA=(double)Math.round(resultGPA*100)/100;
				}
				
				StudentPO studentPO=(StudentPO)userPO;
				studentPO.setGPA(NOW_TERM, resultGPA);
				studentPO.setTotalCredit(totalCredit);
				studentPO.setTotalSelectedCredit(totalChooseCredit);
				userDatabaseService.update(studentPO);
			}
			
			
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
		
	}

	@Override
	public ArrayList<ChooseCourseVO> getDeleteChooseCourseRecord()
			throws Exception {
		ArrayList<ChooseCourseVO> chooseCourseVOlist=new ArrayList<ChooseCourseVO>();
		try {
			
			ChooseCourseDatabaseService chooseCourseDatabaseService
			  =(ChooseCourseDatabaseService)Naming.lookup("rmi://"+ADDRESS_STRING+":8888/chooseCourseData");
			
			ArrayList<ChooseCoursePO> chooseCoursePOs
			        =chooseCourseDatabaseService.findChooseCourseByIDAndTerm(userId, NOW_TERM);
			for(ChooseCoursePO choose:chooseCoursePOs){
				if (choose.getAttribute().equals("开放选修")) {
					ChooseCourseVO chooseCourseVO=new ChooseCourseVO(choose.getStudentId(),
							   choose.getStudentName(),choose.getCourseId(),choose.getCourseName(),choose.getScore(),choose.getCredit(),choose.getTerm(),choose.getAttribute());
								chooseCourseVOlist.add(chooseCourseVO);
				}
				
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
		return chooseCourseVOlist;	
	}

	@Override
	public ArrayList<ChooseCourseVO> getAllStudentChoose() throws Exception {
		ArrayList<ChooseCourseVO> chooseCourseVOlist=new ArrayList<ChooseCourseVO>();
		try {

			
			ChooseCourseDatabaseService chooseCourseDatabaseService
			  =(ChooseCourseDatabaseService)Naming.lookup("rmi://"+ADDRESS_STRING+":8888/chooseCourseData");
			
			ArrayList<ChooseCoursePO> chooseCoursePOs
			        =chooseCourseDatabaseService.findAllChooseCourseTemp();
			for(ChooseCoursePO choose:chooseCoursePOs){
				ChooseCourseVO chooseCourseVO=new ChooseCourseVO(choose.getStudentId(),
			   choose.getStudentName(),choose.getCourseId(),choose.getCourseName(),choose.getScore(),choose.getCredit(),choose.getTerm(),choose.getAttribute());
				chooseCourseVOlist.add(chooseCourseVO);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
		return chooseCourseVOlist;	
		
	}

	@Override
	public ArrayList<ChooseCourseVO> sortChooseCourse() throws Exception {
		ArrayList<ChooseCoursePO> resultPO;
		ArrayList<ChooseCourseVO> resultVO=new ArrayList<>();
		ChooseCourseDatabaseService chooseCourseDatabaseService
		  =(ChooseCourseDatabaseService)Naming.lookup("rmi://"+ADDRESS_STRING+":8888/chooseCourseData");
		try {
			 resultPO=chooseCourseDatabaseService.sortChooseCourse();
			 for(ChooseCoursePO chooseCoursePO:resultPO){
				 resultVO.add(new ChooseCourseVO(chooseCoursePO.getStudentId(), chooseCoursePO.getStudentName(), chooseCoursePO.getCourseId(),
						 chooseCoursePO.getCourseName(), chooseCoursePO.getScore(), chooseCoursePO.getCredit(), 
						 chooseCoursePO.getTerm(), chooseCoursePO.getAttribute()));
			 }
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
		return resultVO;
	}

	@Override
	public ArrayList<CourseVO> getMyDeleteCourse() throws Exception {
		ArrayList<ChooseCourseVO> chooseCourseVOs=getDeleteChooseCourseRecord();
		ArrayList<CourseVO> courseVOs=new ArrayList<>();
		CourseController courseController=new CourseController(userId);
		for(ChooseCourseVO chooseCourseVO:chooseCourseVOs){
			courseVOs.add(courseController.getCourse(chooseCourseVO.getCourseId()));
		}
		return courseVOs;
	}

	@Override
	public ResultMessage chooseCourseDirect(ChooseCourseVO chooseCourseVO)
			throws Exception {

		ResultMessage resultMessage=null;
		ChooseCourseDatabaseService chooseCourseDatabaseService;
		
		try {
			 chooseCourseDatabaseService=(ChooseCourseDatabaseService)Naming.lookup("rmi://"+ADDRESS_STRING+":8888/chooseCourseData");
			 
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
		ChooseCoursePO chooseCoursePO=new ChooseCoursePO(chooseCourseVO.getStudentId(), chooseCourseVO.getStudentName(),chooseCourseVO.getCourseId(),chooseCourseVO.getCourseName(),
				                          chooseCourseVO.getScore(),chooseCourseVO.getCreidt(),chooseCourseVO.getTerm(),chooseCourseVO.getAttribute());
		
		resultMessage= chooseCourseDatabaseService.insert(chooseCoursePO);
		return resultMessage;
		
	}

	@Override
	public ArrayList<CourseVO> getMyTemp() throws Exception {
		ChooseCourseDatabaseService chooseCourseDatabaseService;
		
		try {
			 chooseCourseDatabaseService=(ChooseCourseDatabaseService)Naming.lookup("rmi://"+ADDRESS_STRING+":8888/chooseCourseData");
			 
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
		ArrayList<ChooseCoursePO> chooseCoursePOs= chooseCourseDatabaseService.findChooseCourseByIDAndTermTemp(userId, NOW_TERM);
		CourseController courseController=new CourseController(userId);
		ArrayList<CourseVO> courseVOs=new ArrayList<>();
		for(ChooseCoursePO chooseCoursePO:chooseCoursePOs){
			courseVOs.add(courseController.getCourse(chooseCoursePO.getCourseId()));
		}
		return courseVOs;
	}
	
	
	
	
}
